using System;
using System.Threading.Tasks;
using System.Linq;
using ApiProject.Api.Entity;
using ApiProject.Api.Data;
using Microsoft.EntityFrameworkCore;
using System.Collections.Generic;
namespace ApiProject.Api.Repository
{
    public class EfRepository<T> : IRepository<T> where T : BaseEntity
    {

        private ApiProjectDb _db;

        public EfRepository(ApiProjectDb db)
        {
            _db = db;
        }


        private DbSet<T> _entity;

        protected DbSet<T> Entity
        {
            get
            {
                if (_entity == null)
                {
                    _entity = _db.Set<T>();
                }
                return _entity;
            }
        }

        public IQueryable<T> Table
        {
            get
            {
                return Entity.AsQueryable<T>();
            }
        }

        public void Delete(int id)
        {
            var dc = Entity.Where(x => x.Id == id).Where(o =>o.IsDelete==false).FirstOrDefault();
            Entity.Remove(dc);
            _db.SaveChanges();
        }

        public T GetById(int id)
        {
            var dc = Entity.Where(x => x.Id == id).Where(o =>o.IsDelete==false).FirstOrDefault();
            return dc;
        }

        public void Insert(T entity)
        {
            if (entity == null)
            {
                throw new System.ArgumentNullException();
            }

            entity.CreatedTime = DateTime.Now;
            entity.UpdatedTime = DateTime.Now;
            entity.DisplayOrder = 0;

            Entity.Add(entity);
            _db.SaveChanges();
        }

        public async Task InsertAsync(T entity)
        {
            if (entity == null)
            {
                throw new System.NullReferenceException();
            }
            entity.CreatedTime = DateTime.Now;
            entity.UpdatedTime = DateTime.Now;
            entity.DisplayOrder = 0;

            await Entity.AddAsync(entity);
            await _db.SaveChangesAsync();
        }


        public void InsertBulk(IEnumerable<T> entities)
        {

            foreach (var entity in entities)
            {
                entity.CreatedTime = DateTime.Now;
                entity.UpdatedTime = DateTime.Now;
                entity.DisplayOrder = 0;
            }
            Entity.AddRange(entities);
            _db.SaveChanges();
        }


        public async Task InsertBulkAsync(IEnumerable<T> entities)
        {
            foreach (var entity in entities)
            {

                entity.CreatedTime = DateTime.Now;
                entity.UpdatedTime = DateTime.Now;
                entity.DisplayOrder = 0;
            }
            await Entity.AddRangeAsync(entities);
            await _db.SaveChangesAsync();
        }




        public void Update(T entity)
        {
            if (entity == null)
            {
                throw new System.NullReferenceException();
            }
            entity.UpdatedTime = DateTime.Now;
            _db.SaveChanges();
        }

        public void UpdateBulk(IEnumerable<T> entities)
        {
            foreach (var entity in entities)
            {
                entity.UpdatedTime = DateTime.Now;
            }
            _db.SaveChanges();
        }
    }
}